﻿/*******************************************************************************
 * Level Master 2000
 * Copyright (C) 2010 Christian Herzog
 * For more information see http://code.google.com/p/levelmaster2000/
 *
 * This file is licensed under the terms of the MIT license, see
 * http://www.opensource.org/licenses/mit-license.php for further information.
 ******************************************************************************/

package
{
    import com.pblabs.animation.AnimatorComponent;
    import com.pblabs.box2D.*;
    import com.pblabs.box2D.Box2DDebugComponent;
    import com.pblabs.box2D.Box2DManagerComponent;
    import com.pblabs.box2D.Box2DSpatialComponent;
    import com.pblabs.box2D.CircleCollisionShape;
    import com.pblabs.box2D.PolygonCollisionShape;
    import com.pblabs.components.basic.HealthComponent;
    import com.pblabs.engine.core.*;
    import com.pblabs.engine.core.LevelManager;
    import com.pblabs.engine.entity.*;
    import com.pblabs.engine.entity.IEntity;
    import com.pblabs.engine.PBE;
    import com.pblabs.rendering2D.*;
    import com.pblabs.rendering2D.DisplayObjectScene;
    import com.pblabs.rendering2D.SimpleSpatialComponent;
    import com.pblabs.rendering2D.spritesheet.CellCountDivider;
    import com.pblabs.rendering2D.spritesheet.SpriteSheetComponent;
    import com.pblabs.rendering2D.SpriteSheetRenderer;
    import com.pblabs.rendering2D.ui.*;
    import com.pblabs.rendering2D.ui.SceneView;
    import com.zog.Box2DTrigger;
    import com.zog.CharacterController;
    import com.zog.DamageEntityOnCollision;
    import com.zog.DestroyEntityOnCollision;
    import com.zog.PlayerLogic;
    import com.zog.SimplePlatform;
    import flash.display.*;
    import flash.display.Sprite;
    import flash.events.*;
    import flash.external.ExternalInterface;
    import flash.geom.Point;
    import flash.geom.Rectangle;
    import flash.utils.*;
    
      
    [SWF(width="800", height="600", frameRate="60", backgroundColor="#08d4f8")]
    public class Demo extends Sprite
    {      
        public function Demo() 
        {
            // Make sure all the types our XML will use are registered.
            PBE.registerType(flash.geom.Point);
            PBE.registerType(flash.geom.Matrix);
            PBE.registerType(flash.geom.Rectangle);
            PBE.registerType(flash.geom.Transform);

            PBE.registerType(com.pblabs.engine.PBE);
            PBE.registerType(com.pblabs.engine.core.LevelManager);
            PBE.registerType(com.pblabs.animation.AnimatorComponent);

            PBE.registerType(com.pblabs.rendering2D.SpriteRenderer);
			PBE.registerType(com.pblabs.rendering2D.DisplayObjectScene);
            PBE.registerType(com.pblabs.rendering2D.SpriteSheetRenderer);
            PBE.registerType(com.pblabs.rendering2D.SimpleSpatialComponent);
            
            PBE.registerType(com.pblabs.rendering2D.spritesheet.SpriteSheetComponent);
            PBE.registerType(com.pblabs.rendering2D.spritesheet.CellCountDivider);
            PBE.registerType(com.pblabs.rendering2D.ui.SceneView);
            
            PBE.registerType(com.pblabs.box2D.Box2DDebugComponent);
            PBE.registerType(com.pblabs.box2D.Box2DManagerComponent);
            PBE.registerType(com.pblabs.box2D.Box2DSpatialComponent);
            PBE.registerType(com.pblabs.box2D.PolygonCollisionShape);
            PBE.registerType(com.pblabs.box2D.CircleCollisionShape);
        
            PBE.registerType(DestroyEntityOnCollision);
            PBE.registerType(DamageEntityOnCollision);
			PBE.registerType(SimplePlatform);
			PBE.registerType(CharacterController);
			PBE.registerType(HealthComponent);
			PBE.registerType(PlayerLogic);
			PBE.registerType(Box2DTrigger);

            if (this.stage)
            {
                onAddedToStage();
            } 
            else 
            {
                addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
            }
        }

        private function createBox2DDebugView():void
        {
            if(PBE.nameManager.lookup("DEBUG") == null)
            {
                var e:IEntity = PBE.allocateEntity();
                e.initialize("DEBUG");

                var c:Box2DDebugComponent = new Box2DDebugComponent();
                c.spatialManager = PBE.spatialManager as Box2DManagerComponent;
                c.scene = PBE.scene;
                
                e.addComponent(c, "visual");
            }
        }
        
        private function onLevelLoaded(e:Event):void 
		{
            createBox2DDebugView();
		}   
        
        public function createRollingStone():IEntity
        {
            var stoneEnt:IEntity = PBE.allocateEntity();
            var entName:String = PBE.nameManager.validateName("RollingStone");
            stoneEnt.initialize(entName);

            //Create our spatial component / body:
            var spatialComp:Box2DSpatialComponent = new Box2DSpatialComponent();
            spatialComp.spatialManager= PBE.spatialManager as Box2DManagerComponent;
            spatialComp.position = new Point(000, 000);
            spatialComp.size = new Point(1, 1);
            spatialComp.collisionType = new ObjectType("HurtObject");
            spatialComp.canMove = true;
            spatialComp.canRotate = true;
            spatialComp.canSleep = true;
            spatialComp.collidesWithTypes = new ObjectType("Player", "Platform");
            
            //We also need a collision shape, which collides with the world (meaning other shapes):
            var shape:CircleCollisionShape = new CircleCollisionShape();
            shape.radius = 48.0;
            shape.density = 1;
            shape.friction = 1.0;
            shape.restitution = 0.0;
            
            //Now we add the shape to the spatial component / body:
            spatialComp.collisionShapes = new Array();
            spatialComp.collisionShapes.push(shape);
             
            //Add the component to the entity:
            stoneEnt.addComponent( spatialComp, "Spatial" ); 			

            //don't forget to build the collision shapes after adding component:		
            spatialComp.buildCollisionShapes(); 
			
			//Since we want to visualize the entity, we need a simple sprite renderer:
			var renderComp:SpriteRenderer = new SpriteRenderer(); 

			renderComp.scene = PBE.scene;
			renderComp.fileName = "../assets/Images/rock.png";
			renderComp.positionProperty  = new PropertyReference("@Spatial.position");
			renderComp.rotationProperty = new PropertyReference("@Spatial.rotation");

			//Add the component to the entity:
			stoneEnt.addComponent( renderComp, "Render" )
            
            var hurtPlayerOnCollision:DamageEntityOnCollision = new DamageEntityOnCollision();
            hurtPlayerOnCollision.playerCollisionGroup = "Player";
            hurtPlayerOnCollision.damage = 100;
            stoneEnt.addComponent(hurtPlayerOnCollision, "HurtPlayerOnCollision");            
            
            return stoneEnt;
        }
        
        private function onAddedToStage(evt:Event = null):void 
        {
            removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage);

			//Initialize the engine
            PBE.startup(this);
            
			// Load embedded resources.
            new Resources();
            
            var sceneView:SceneView = new SceneView();
			
            PBE.initializeScene( sceneView, "Scene", null, Box2DManagerComponent );
            
			PBE.scene.screenPan( 180, 120 );
			
            PBE.levelManager.addEventListener(LevelEvent.LEVEL_LOADED_EVENT, onLevelLoaded);
            
			if(!ExternalInterface.available)
			{
				LevelManager.instance.load("../assets/levelDescriptions.xml", 1);
			}
            
			PBE.templateManager.registerEntityCallback("RollingStone", createRollingStone);
		}
    }
}
